home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
man
/
cat.1
/
perlsec.1
< prev
next >
Wrap
Text File
|
1995-07-25
|
9KB
|
199 lines
PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
NNNNAAAAMMMMEEEE
perlsec - Perl security
DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
Perl is designed to make it easy to write secure setuid and
setgid scripts. Unlike shells, which are based on multiple
substitution passes on each line of the script, Perl uses a
more conventional evaluation scheme with fewer hidden
"gotchas". Additionally, since the language has more
built-in functionality, it has to rely less upon external
(and possibly untrustworthy) programs to accomplish its
purposes.
Beyond the obvious problems that stem from giving special
privileges to such flexible systems as scripts, on many
operating systems, setuid scripts are inherently insecure
right from the start. This is because that between the time
that the kernel opens up the file to see what to run, and
when the now setuid interpreter it ran turns around and
reopens the file so it can interpret it, things may have
changed, especially if you have symbolic links on your
system.
Fortunately, sometimes this kernel "feature" can be
disabled. Unfortunately, there are two ways to disable it.
The system can simply outlaw scripts with the setuid bit
set, which doesn't help much. Alternately, it can simply
ignore the setuid bit on scripts. If the latter is true,
Perl can emulate the setuid and setgid mechanism when it
notices the otherwise useless setuid/gid bits on Perl
scripts. It does this via a special executable called
ssssuuuuiiiiddddppppeeeerrrrllll that is automatically invoked for you if it's
needed.
If, however, the kernel setuid script feature isn't
disabled, Perl will complain loudly that your setuid script
is insecure. You'll need to either disable the kernel
setuid script feature, or put a C wrapper around the script.
See the program wwwwrrrraaaappppssssuuuuiiiidddd in the _e_g directory of your Perl
distribution for how to go about doing this.
There are some systems on which setuid scripts are free of
this inherent security bug. For example, recent releases of
Solaris are like this. On such systems, when the kernel
passes the name of the setuid script to open to the
interpreter, rather than using a pathname subject to
mettling, it instead passes /dev/fd/3. This is a special
file already opened on the script, so that there can be no
race condition for evil scripts to exploit. On these
systems, Perl should be compiled with
-DSETUID_SCRIPTS_ARE_SECURE_NOW. The CCCCoooonnnnffffiiiigggguuuurrrreeee program that
builds Perl tries to figure this out for itself.
Page 1 (printed 6/30/95)
PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
When Perl is executing a setuid script, it takes special
precautions to prevent you from falling into any obvious
traps. (In some ways, a Perl script is more secure than the
corresponding C program.) Any command line argument,
environment variable, or input is marked as "tainted", and
may not be used, directly or indirectly, in any command that
invokes a subshell, or in any command that modifies files,
directories, or processes. Any variable that is set within
an expression that has previously referenced a tainted value
also becomes tainted (even if it is logically impossible for
the tainted value to influence the variable). For example:
$foo = shift; # $foo is tainted
$bar = $foo,'bar'; # $bar is also tainted
$xxx = <>; # Tainted
$path = $ENV{'PATH'}; # Tainted, but see below
$abc = 'abc'; # Not tainted
system "echo $foo"; # Insecure
system "/bin/echo", $foo; # Secure (doesn't use sh)
system "echo $bar"; # Insecure
system "echo $abc"; # Insecure until PATH set
$ENV{'PATH'} = '/bin:/usr/bin';
$ENV{'IFS'} = '' if $ENV{'IFS'} ne '';
$path = $ENV{'PATH'}; # Not tainted
system "echo $abc"; # Is secure now!
open(FOO,"$foo"); # OK
open(FOO,">$foo"); # Not OK
open(FOO,"echo $foo|"); # Not OK, but...
open(FOO,"-|") || exec 'echo', $foo; # OK
$zzz = `echo $foo`; # Insecure, zzz tainted
unlink $abc,$foo; # Insecure
umask $foo; # Insecure
exec "echo $foo"; # Insecure
exec "echo", $foo; # Secure (doesn't use sh)
exec "sh", '-c', $foo; # Considered secure, alas
The taintedness is associated with each scalar value, so
some elements of an array can be tainted, and others not.
If you try to do something insecure, you will get a fatal
error saying something like "Insecure dependency" or
"Insecure PATH". Note that you can still write an insecure
system call or exec, but only by explicitly doing something
like the last example above. You can also bypass the
Page 2 (printed 6/30/95)
PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((RRRReeeelllleeeeaaaasssseeee 0000....0000 PPPPaaaattttcccchhhhlllleeeevvvveeeellll 00000000)))) PPPPEEEERRRRLLLLSSSSEEEECCCC((((1111))))
tainting mechanism by referencing subpatterns--Perl presumes
that if you reference a substring using $1, $2, etc, you
knew what you were doing when you wrote the pattern:
$ARGV[0] =~ /^-P(\w+)$/;
$printer = $1; # Not tainted
This is fairly secure since \w+ doesn't match shell
metacharacters. Use of /.+/ would have been insecure, but
Perl doesn't check for that, so you must be careful with
your patterns. This is the _O_N_L_Y mechanism for untainting
user supplied filenames if you want to do file operations on
them (unless you make $> equal to $< ).
For "Insecure PATH" messages, you need to set $ENV{'PATH}'
to a known value, and each directory in the path must be
non-writable by the world. A frequently voiced gripe is
that you can get this message even if the pathname to an
executable is fully qualified. But Perl can't know that the
executable in question isn't going to execute some other
program depending on the PATH.
It's also possible to get into trouble with other operations
that don't care whether they use tainted values. Make
judicious use of the file tests in dealing with any user-
supplied filenames. When possible, do opens and such after
setting $> = $<. (Remember group IDs, too!) Perl doesn't
prevent you from opening tainted filenames for reading, so
be careful what you print out. The tainting mechanism is
intended to prevent stupid mistakes, not to remove the need
for thought.
Page 3 (printed 6/30/95)